package cn.rumoss.jvm.deep.oom;

public class StringInternJDK8 {

	public static void main(String[] args) {

		//test1();
		//test2();
		//test3();
		//test4();
		test5();
		//test6();
		//test7();
	}

	public static void test1() {
		String s1 = "AA";
		String s2 = "AA";
		System.out.println(s1 == s2);// true
	}
	
	public static void test2() {
		String s1 = new String("AA");
		s1.intern();// 常量池里面的字符串AA
		System.out.println(s1 == s1.intern());// false
		String s2 = "AA";// 拿到是常量池里面的AA
		System.out.println(s1 == s2);// false
		System.out.println(s2 == s1.intern());// true
	}
	
	/**
	 * 双引号相加
	 */
	public static void test3() {
		String s1 = "AA" + "BB";
		String s2 = "AABB";
		String s3 = "AAB" + "B";
		String s4 = "A" + "ABB";
		System.out.println(s1 == s3);// true
		System.out.println(s2 == s4);// true
	}
	
	/**
	 * new String()相加
	 */
	public static void test4() {
		//常量AA不存在，所以第一步在常量池中创建了常量AA
	    String s1 = new String("AA") + new String("BB");
	    String s2 = new String("A")+new String("A"); //创建对象"AA"
	    s2.intern();// 拿到是常量池里面的AA
	    System.out.println(s2 == s2.intern()); //false
	    s2 = new String("AA")+new String("A"); //创建对象"AAA"
	    s2.intern();// 放入对象"AAA"的引用到常量池
	    System.out.println(s2 == s2.intern()); //true
	}
	
	/**
	 * new String()相加
	 */
	public static void test5() {
		// 只在堆上创建"AABB"对象，没有在常量池中创建AABB字符串，但有"AA"和"BB"
		String s1 = new String("AA") + new String("BB");// true true false true
		//String s1 = new String("A") + new String("ABB");// true true true true
		s1.intern();// 常量池里面放的是"AABB"的引用
		//System.out.println(s1 == s1.intern());// true
		String s11 = "AABB";// 拿到的也是"AABB"对象的引用，没有在常量池创建AABB字符串
		System.out.println(s11 == s1.intern());
		
		String s2 = new String("A") + new String("A");// 创建对象"AA"
		//s2.intern();// 拿到的是常量池的AA(已存在)
		s2.intern();// 拿到的是常量池对象"AA"引用
		System.out.println(s2 == s2.intern());
		String s3 = "AA";
		System.out.println(s3 == s2.intern());
	}
	
	public static void test6() {
		// 只在堆上创建"AABB"对象，没有在常量池中创建AABB字符串
		String s1 = new String("AA") + new String("BB");
		s1.intern();
		System.out.println(s1 == s1.intern());// true
		// "AABB"也是常量池的引用
		System.out.println("AABB" == s1.intern());// true
		String s2 = "AABB";// 以后拿到的都是前面的引用
		System.out.println(s2 == s1.intern());// true
		String s3 = "A" + "ABB";
		System.out.println(s3 == s1.intern());// true
	}
	
	public static void test7() {
		String s1 = "AABB";
		String s2 = "AA" + new String("BB");
		System.out.println(s1 == s2);// false
		System.out.println(s1 == s2.intern());// true
	}
	
}
